package cn.mini.mybatis.builder.xml;

import cn.mini.mybatis.builder.BaseBuilder;
import cn.mini.mybatis.mapping.SqlCommandType;
import cn.mini.mybatis.io.Resources;
import cn.mini.mybatis.mapping.MappedStatement;
import cn.mini.mybatis.session.Configuration;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.xml.sax.InputSource;

import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class XMLMapperBuilder extends BaseBuilder {

    private Reader reader;
    private String resource;

    // 该正则表达式用于匹配SQL模板中的占位符 #{}，例如：
    // 在 SQL 语句中形如：SELECT * FROM users WHERE id = #{id} AND name = #{name}
    // 正则会匹配到 "#{id}" 和 "#{name}"，并捕获其中的变量名供后续替换为 ? 并构建参数映射
    Pattern pattern = Pattern.compile("(#\\{(.*?)})");

    public XMLMapperBuilder(Reader reader, String resource , Configuration configuration) {
        super(configuration);
        this.reader = reader;
        this.resource = resource;
    }

    public void parse() {
        SAXReader saxReader = new SAXReader();
        Document mapperDoc = null;
        try {
            mapperDoc = saxReader.read(new InputSource(reader));
        } catch (DocumentException e) {
            throw new RuntimeException(e);
        }
        Element mapperRoot = mapperDoc.getRootElement();
        String namespace = mapperRoot.attributeValue("namespace");

        if (namespace == null || namespace.trim().isEmpty()) {
            throw new IllegalArgumentException("Namespace cannot be empty in " + resource);
        }

        for (Element sqlElement : mapperRoot.elements()) {
            String id = sqlElement.attributeValue("id");

            if (id == null || id.trim().isEmpty()) {
                throw new IllegalArgumentException("SQL id cannot be empty in " + resource);
            }

            String sqlCommandName = sqlElement.getName().toLowerCase();
            SqlCommandType sqlCommandType = SqlCommandType.valueOf(sqlCommandName.toUpperCase());
            String sql = sqlElement.getTextTrim();
            String statementId = namespace + "." + id;

            String parameterType = sqlElement.attributeValue("parameterType");
            String resultType = sqlElement.attributeValue("resultType");
            // 解析sql
            Map<Integer,String > parameter = new HashMap<>();

            Matcher matcher = pattern.matcher(sql);
            for (int i = 1; matcher.find(); i++) {
                String g1 = matcher.group(1);
                String g2 = matcher.group(2);
                parameter.put(i, g2);
                sql = sql.replace(g1, "?");
            }

            MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration,
                    statementId,sqlCommandType,parameterType, resultType, sql,parameter);

            // 注册Mapper映射器
            try {
                configuration.addMapper(Resources.classForName(namespace));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            configuration.addMappedStatement(statementBuilder.build());
        }
    }



}
